//****************************************************************************
// File Name: WineryManager.cpp
// Wine Tours project
// Group #2: Allen McLennan, Ryan Neal, Mike Matz
// CS 1C
// April 28, 2010
// Implementation of WineryManager class
//****************************************************************************


#include "WineryManager.h"

using namespace std;

#define WINERYMANAGER_BUFFER_LEN 50

WineryManager::WineryManager(const char *theFileName) :
		initialized(false),
		numWineries(0) {
	fileName = (char *)malloc(WINERYMANAGER_BUFFER_LEN);
	strncpy(fileName, theFileName, WINERYMANAGER_BUFFER_LEN);
	fileName[WINERYMANAGER_BUFFER_LEN] = 0;
}

WineryManager::~WineryManager() {
	free(fileName);
}

Winery *WineryManager::GetWinery(int id) {
	ifstream fp;
	Winery *w;

	if (id + 1 > WT_MAX_WINERIES) {
		return NULL;
	}

	if (!initialized)
		VerifyFile();

	w = new Winery();

	fp.open(fileName, ios::binary);
	if (fp.fail()) {
		return false;
	}

	fp.seekg((id - 1) * sizeof(*w), ios::beg);
	fp.read((char *)w, sizeof(*w));

	fp.close();

	return w;
}

bool WineryManager::SaveWinery(Winery *w, int id) {
	ofstream fp;

	if (id + 1 > WT_MAX_WINERIES) {
		return false;
	}

	if (w == NULL) {
		return false;
	}

	if (!initialized)
		VerifyFile();

	fp.open(fileName, ios::binary | ios::in);
	if (fp.fail()) {
		return false;
	}

	fp.seekp((id - 1) * sizeof(*w), ios::beg);

	fp.write((char *)w, sizeof(*w));
	fp.close();

	if (id - 1 > numWineries) {
		numWineries = id - 1;
	}

	if (w->GetId() > numWineries) {
		numWineries = w->GetId();
	}

	return false;
}

int WineryManager::GetNumWineries() {
	if (!initialized) {
		VerifyFile();
	}
	return numWineries;
}

void WineryManager::DisplayWineries() {
	int i, j;
	Winery *winery;
	Wine wine;

	cout << "Displaying " << GetNumWineries() << " wineries" << endl << endl;

	for (i = 1; i <= GetNumWineries(); i++) {
		winery = GetWinery(i);
		cout << winery->GetName() << endl;
		for (j = 0; j < winery->GetWineNum(); j++) {
			wine = winery->GetWine(j);
			cout << "  " << setfill(' ') << left << setw(5) << wine.vintage;
			cout << setw(34) << setfill('.') << wine.wineName << right
					<< fixed << setprecision(2) << setw(10)
					<< wine.price << endl;
		}
	}
}

bool WineryManager::ImportWineries(const char *importFileName) {
	ifstream infile;
	int idx, currIdx, numWineries, numWines, k;
	float dist;
	Winery *w;
	Wine wine;
	string str;

	infile.open(importFileName);
	if (infile.fail()) {
		return false;
	}

	for (idx = 1; idx <= WT_MAX_WINERIES; idx++) {
		w = new Winery(idx);

		getline(infile, str);
		w->SetName(str.c_str());

		infile >> currIdx;
		infile.ignore(100, '\n');
		w->SetId(currIdx);

		infile >> numWineries;
		infile.ignore(100, '\n');
		for (k = 0; k < numWineries; k++) {
			infile >> currIdx;
			infile.ignore();
			infile >> dist;
			infile.ignore(100, '\n');
			w->SetDistanceToWinery(currIdx, dist);
		}

		infile >> dist;
		infile.ignore(100, '\n');
		w->SetDistance(dist);

		infile >> numWines;
		infile.ignore(100, '\n');

		for (k = 0; k < numWines; k++) {
			getline(infile, str);
			strcpy(wine.wineName, str.c_str());
			infile >> wine.vintage;
			infile.ignore(100, '\n');
			infile >> wine.price;
			infile.ignore(100, '\n');
			w->AddWine(wine);
		}

		SaveWinery(w, idx);

		delete w;
		w = NULL;

		if (infile.eof()) {
			break;
		}
	}

	infile.close();

	return true;
}

void WineryManager::ResetWineries() {
	InitializeFile();
}

bool WineryManager::VerifyFile() {
	ifstream file;

	if (initialized)
		return true;

	file.open(fileName);
	if (!file.is_open()) {
		file.close();
		InitializeFile();
	} else {
		file.close();
		initialized = true;
		for (int i = 1; i < WT_MAX_WINERIES; i++) {
			Winery *w = GetWinery(i);
			if (!w->GetId()) {
				break;
			}
			numWineries++;
			delete w;
		}
	}

	return initialized;
}

bool WineryManager::InitializeFile() {
	ofstream fp;
	int i;
	Winery temp = Winery();

	fp.open(fileName, ios::binary | ios::trunc);
	if (fp.fail()) {
		return false;
	}

	for (i = 0; i < WT_MAX_WINERIES; i++) {
		fp.write((char *)&temp, sizeof(temp));
	}

	fp.close();

	initialized = true;
	numWineries = 0;

	return true;

}

